package com.kma.ncpractice2013.servlets;

import com.kma.ncpractice2013.dao.*;
import com.kma.ncpractice2013.model.*;
import org.json.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import static java.lang.Math.min;
import static java.lang.Math.max;

/*
 * User: Illyas
 * Date: 11/13/13
 * Time: 10:07 PM
 */

public class ManagerServlet extends HttpServlet
{
    private String getPromoCodesList(String sortBy, boolean showExpired)
    {
        PromoCodeDAO codeDAO = new PromoCodeDAO();
        List<PromoCode> codesList = codeDAO.getAllSortedBy(sortBy,showExpired);
        HashMap<String,List> map = new HashMap<String, List>();
        map.put("codesList",codesList);
        return JSONObject.valueToString(map);
    }

    private String getUsersList(String login, String name, String surname, User.Group group, int page, int entitiesPerPage)
    {
        UserGroupDAO groupDAO = new UserGroupDAO();
        UserAccessLevelDAO accessLevelDAO = new UserAccessLevelDAO();
        List<String> groupList = new ArrayList<String>();
        List<String> accessLevelList = new ArrayList<String>();
        UserDAO userDAO = new UserDAO();
        List<User> userList = userDAO.getRequestedUsersPerPage(login, name, surname, group, page, entitiesPerPage);
        for(User u:userList)
        {
            groupList.add(u.getGroupId().toString());
            accessLevelList.add(u.getAccessLevelId().toString());
        }
        HashMap<String, List> map = new HashMap<String, List>();
        map.put("grouplist", groupList);
        map.put("userlist", userList);
        map.put("accesslevellist", accessLevelList);
        return JSONObject.valueToString(map);
    }

    private String grantVIPStatus(String [] ids)
    {
        ArrayList<Integer> responseIds = new ArrayList<Integer>();
        UserDAO dao = new UserDAO();
        for (String sId : ids)
        {
            try
            {
                Integer id = Integer.parseInt(sId);
                User user = dao.getById(id);
                if (user.getGroupId() != User.Group.nonRegisteredCustomer)
                {
                    user.setGroupId(User.Group.VIPCustomer);
                    dao.update(user);
                    responseIds.add(id);
                }
            }
            catch (Exception e)
            {
            }
        }
        return JSONObject.valueToString(responseIds.toArray());
    }

    private String revokeVIPStatus(String [] ids)
    {
        ArrayList<Integer> responseIds = new ArrayList<Integer>();
        UserDAO dao = new UserDAO();
        for (String sId : ids)
        {
            try
            {
                Integer id = Integer.parseInt(sId);
                User user = dao.getById(id);
                if (user.getGroupId() != User.Group.nonRegisteredCustomer)
                {
                    user.setGroupId(User.Group.ordinaryCustomer);
                    dao.update(user);
                    responseIds.add(id);
                }
            }
            catch (Exception e)
            {
            }
        }
        return JSONObject.valueToString(responseIds.toArray());
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        PrintWriter out = response.getWriter();
        String action = request.getParameter("action");
        if (action.equals("saveDiscounts"))
        {
            String reply = "failure";
            String sNonVIPDiscount = request.getParameter("nonVIPDiscount"),
                    sVIPDiscount = request.getParameter("VIPDiscount");
            Integer nonVIPDiscount = null, VIPDiscount = null;
            try
            {
                nonVIPDiscount = Integer.parseInt(sNonVIPDiscount);
                VIPDiscount = Integer.parseInt(sVIPDiscount);
            }
            catch (NumberFormatException e)
            {
                // TODO: add logging
            }
            if (Discount.isValid(nonVIPDiscount) && Discount.isValid(VIPDiscount))
            {
                UserGroupDAO dao = new UserGroupDAO();
                UserGroup group = dao.getById(User.Group.ordinaryCustomer.getValue());
                group.setDiscount(nonVIPDiscount);
                dao.update(group);
                group = dao.getById(User.Group.VIPCustomer.getValue());
                group.setDiscount(VIPDiscount);
                dao.update(group);
                reply = "success";
            }
            out.print(reply);
        }
        else if (action.equals("saveCommission"))
        {
            String reply = "failure";
            Integer commission = null;
            try
            {
                commission = Integer.parseInt(request.getParameter("commission"));
            }
            catch (NumberFormatException e)
            {
            }
            boolean ok = Commission.trySetValue(commission);
            if (ok)
                reply = "success";
            out.print(reply);
        }
        else if (action.equals("generatePromocodes"))
        {
            String reply = "success";
            try
            {
                Integer discount = Integer.parseInt(request.getParameter("discount"));
                if (!Discount.isValid(discount))
                    throw new Exception("Discount value not in the admissible range");
                String ssDate = request.getParameter("startDate"),
                        seDate = request.getParameter("endDate");
                Date sDate = null, eDate = null;
                sDate = Date.valueOf(ssDate);
                eDate = Date.valueOf(seDate);
                Integer number = Integer.parseInt(request.getParameter("number"));
                number = Math.min(number,1000);
                number = Math.max(number,0);
                PromoCodeDAO codeDao = new PromoCodeDAO();
	            String codeValue;
	            int i = 0;
                while (i<number)
                {
	                codeValue = UUID.randomUUID().toString().substring(0,8);
	                if (codeDao.getByCode(codeValue) != null)
                        continue;
                    PromoCode code = new PromoCode();
                    code.setDiscount(discount);
                    code.setStartDate(sDate);
                    code.setExpirationDate(eDate);
                    code.setCode(codeValue);
                    codeDao.create(code);
	                i++;
                }
            }
            catch (Exception e)
            {
                reply = "failure";
            }
            out.print(reply);
        }
        else if (action.equals("getPromocodes"))
        {
            String order = request.getParameter("sortBy");
            if (order.equals("startingDate"))
                order = "start_date";
            else if (order.equals("duration"))
                order = "(expiration_date - start_date)";
            else
                order = "id";
            String showExpired = request.getParameter("showExpired");
            boolean show = false;
            if (showExpired.equals("true"))
                show = true;
            out.print(getPromoCodesList(order,show));
        }
        else if (action.equals("getUsersCount"))
        {
            String login = request.getParameter("login");
            if (login.isEmpty())
                login = null;
            String name = request.getParameter("name");
            if (name.isEmpty())
                name = null;
            String surname = request.getParameter("surname");
            if (surname.isEmpty())
                surname = null;
            Integer iUserGroup = null;
            User.Group group = null;
            try
            {
                iUserGroup = Integer.parseInt(request.getParameter("usergroup"));
                // if iUserGroup == 4 then both VIPs and non-VIPs will be displayed
                // that's why the "group" variable will be null
                group = User.Group.getByValue(iUserGroup);
                if (group == User.Group.nonRegisteredCustomer)
                    group = null;
            }
            catch (Exception e)
            {
            }
            UserDAO userDAO = new UserDAO();
            int count = userDAO.getRequestedUsersCount(login, name, surname, group);
            out.print(count);
        }
        else if (action.equals("getUsersList"))
        {
            String login = request.getParameter("login");
            if (login.isEmpty())
                login = null;
            String name = request.getParameter("name");
            if (name.isEmpty())
                name = null;
            String surname = request.getParameter("surname");
            if (surname.isEmpty())
                surname = null;
            Integer iUserGroup = null;
            User.Group group = null;
            try
            {
                iUserGroup = Integer.parseInt(request.getParameter("usergroup"));
                // if iUserGroup == 4 then both VIPs and non-VIPs will be displayed
                // that's why the "group" variable will be null
                group = User.Group.getByValue(iUserGroup);
                if (group == User.Group.nonRegisteredCustomer)
                    group = null;
            }
            catch (Exception e)
            {
            }
            Integer itemsPerPage = null;
            try
            {
                itemsPerPage = Integer.parseInt(request.getParameter("itemsPerPage"));
            }
            catch (Exception e)
            {
                itemsPerPage = 10;
            }
            Integer pageNumber = null;
            try
            {
                pageNumber = Integer.parseInt(request.getParameter("pageNumber"));
                --pageNumber;
            }
            catch (Exception e)
            {
                pageNumber = 0;
            }
            out.print(getUsersList(login,name,surname,group,pageNumber,itemsPerPage));
        }
        else if (action.equals("grantVIPStatus"))
        {
            String[] ids = null;
            try
            {
                ids = request.getParameterValues("ids[]");
                if (ids != null)
                    out.print(grantVIPStatus(ids));
            }
            catch (NumberFormatException e)
            {
            }
        }
        else if (action.equals("revokeVIPStatus"))
        {
            String[] ids = null;
            try
            {
                ids = request.getParameterValues("ids[]");
                if (ids != null)
                    out.print(revokeVIPStatus(ids));
            }
            catch (NumberFormatException e)
            {
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {

    }
}
